package com.numberone.web.controller.wx;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.numberone.common.utils.IpUtils;
import com.numberone.system.domain.XyOrder;
import com.numberone.system.service.impl.XyOrderServiceImpl;
import com.numberone.system.util.CommonUtilsYpl;
import com.numberone.web.controller.config.ConfigUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;


@RestController
@RequestMapping("/api/wxOrder")
@Slf4j
@Transactional(propagation = Propagation.REQUIRED)
public class WxController {

    public static final SortedMap<String, String> PARAMS = new TreeMap<>();
    public static final String ISO_8859_1 = "iso-8859-1";
    @Autowired
    private XyOrderServiceImpl xyOrderService;
    @GetMapping("/add")
    public void order(Long orderId, HttpServletResponse response,HttpServletRequest request) throws Exception {
        XyOrder order = xyOrderService.selectXyOrderById(orderId);

        //拿到一个code_url 扫码的地址
        String code_url = unfiedOrder(order,request);
//        if (code_url == null){
//            throw new LogicException("没有拿微信的code_url");
//
//        }
        try{
            //生成二维码
            Map<EncodeHintType,Object> hints = new HashMap<>();
            //设置纠错等级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
            hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");


            //生成二维码的格式 参数1为路径code_url 为格式 3,4为宽高,5为二维码的配置
            BitMatrix bitMatrix = new MultiFormatWriter()
                    .encode("谁扫谁傻逼?",
                            BarcodeFormat.QR_CODE,400,400,hints);
            OutputStream outputStream =  response.getOutputStream();

            MatrixToImageWriter.writeToStream(bitMatrix,"png",outputStream);
        }catch (Exception e){
            e.printStackTrace();
        }



    }

    /**
     * 统一下单方法
     * @return
     */
    private String unfiedOrder(XyOrder order,HttpServletRequest request) throws Exception {
        //BigDecimal ordPrice = order.getOrderPrice();

        //BigDecimal bigPrice = YuanByFenUtil.yuanByFen(new Double(ordPrice.doubleValue()),"100",2);
       // String price = bigPrice.toString();
        //生成签名
        SortedMap<String,String> PARAMS = new TreeMap<>();
        PARAMS.put("appid", ConfigUtil.APPID);   //公众号的appid
        PARAMS.put("mch_id",ConfigUtil.MCH_ID);    //商户号appid
        PARAMS.put("nonce_str", CommonUtilsYpl.generateUUID());
        PARAMS.put("body","订单内容");     //订单的内容
        PARAMS.put("out_trade_no","123"); //商品订单号
        PARAMS.put("total_fee","tostring");  //订单的钱数
        String ip =  IpUtils.getIpAddr(request);
        log.info("我是ip地址"+ip);
        PARAMS.put("spbill_create_ip",ip); //用户的ip
        PARAMS.put("notify_url",ConfigUtil.NOTIFY_URL);  //回调地址
        PARAMS.put("trade_type", "NATIVE");  //支付类型

        //生成签名
        String sign  = WXPayUtil.createSign(PARAMS,ConfigUtil.API_KEY);
        PARAMS.put("sign",sign);

        //map转xml
        String payXml  =  WXPayUtil.mapToXml(PARAMS);
        System.out.println("我是xml"+payXml);


        //统一下单 发起请求下单,得到微信返回结果
        String orderStr  = HttpUtilsYpl.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder",payXml,4000);

        System.out.println(orderStr);
        String s2 = new String(orderStr.getBytes(ISO_8859_1),"utf-8");
        log.info("我是微信返回的数据"+s2);


        if(null == orderStr){
            return  null;
        }
        Map<String,String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr);
        System.out.println("我是返回值:"+unifiedOrderMap);

        if (unifiedOrderMap!=null){
            return unifiedOrderMap.get("code_url");
        }
        return null;
    }

    /**
     * 回调接口
     * @return
     */
    @RequestMapping("/xycallback")
    public Object xyCallBack(HttpServletResponse response, HttpServletRequest request) throws Exception {
        //微信回调都是通过流发送的
        InputStream inputStream = request.getInputStream();
        BufferedReader in  = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = in.readLine())!=null){
            sb.append(line);
        }
        in.close();
        inputStream.close();
        //以上拿到微信回发的所有数据

        //拿到转换后的数据
        Map<String,String> callbackMap = WXPayUtil.xmlToMap(sb.toString());
        System.err.println("我是转换后的数据" +callbackMap.toString());

        //我是排序后的数据
        SortedMap<String, String> sortedMap = WXPayUtil.getSortedMap(callbackMap);

        //1.签名校验
        if (WXPayUtil.isCorrectSign(sortedMap,ConfigUtil.API_KEY)){
            System.out.println(sortedMap);

            //如果签名对了再判断微信返回的是不是成功
            if ("SUCCESS".equals(sortedMap.get("result_code"))){
                //2.更新订单状态
                String outTradeNo = sortedMap.get("out_trade_no");

                //拿着上面的订单号去数据库把订单查出来
                //XyOrder order = xyOrderService.selectXyOrderByOrderNo(outTradeNo);
                XyOrder orderArgs = new XyOrder();

                //查出来以后判断状态是否为0(未支付状态)
                if(orderArgs!=null && orderArgs.getStatus() ==0){
                    //更新订单的状态
                    XyOrder  order = new XyOrder();
                    order.setStatus(1);
                    order.setOrderNumber("订单号");
                   // order.setOpenid(sortedMap.get("openid"));
                    order.setStatus(3);

                    //order.setnotifytime(new Date()) 支付时间
                    int row = xyOrderService.updateXyOrder(order);
                    //3.影响行数 row==1 或者row==0 响应微信成功或失败
                    if (row ==1){  //修改成功
                        response.setContentType("text/html");
                        response.getWriter().print("success");
                        return null;
                    }
                }

            }
        }

        response.setContentType("text/html");
        response.getWriter().print("fail");;
       return  null;
    }

}